﻿# -*- coding: UTF-8 -*-
import Pyro4
import sqlite3
import vue as v
import socket
import sys
import action
import random
import math

sys.path.append("../Generation-Galaxie")
sys.path.append("../Objets-Ali")
import Galaxie
import Systeme
import Planete
import entite
import joueur
import batiment

class Partie():
    def __init__(self, controleur, worldSize, widthEspaceJeu, heightEspaceJeu):
        self.controleur = controleur
        self.worldSize = worldSize
        self.widthEspaceJeu = widthEspaceJeu
        self.heightEspaceJeu = heightEspaceJeu
        
        self.etapeEnCours = "Login" #Determine quelle etape est en cuors pour que le controleur effectue les traitements necessaires
        self.currentFrame = 0 
        self.listePrix = ListePrix()
        self.joueur = None #Joueur local
        self.joueurs = [] #Liste de tous les joueurs
        self.seed = None #Seed pour que tous les clients utilisent le meme "random" et generent la meme galaxie
        
        self.loginDejaAffiche = False
        self.lobbyDejaAffiche = False
        self.initialisationPartieEnvoyee = False
        self.initialisationPartieTerminee = False
                
    def debutPartie(self):
        nomsJoueurs = self.controleur.creerListeJoueurs()
        compteurIdJoueur = 0
        
        for nomJoueur in nomsJoueurs: #On cree des objets joueur a l'aide de leur nom retourne par le serveur
            if nomJoueur == self.joueur.nom: #Si le joueur est nous-meme, l'objet est deja cree, donc on ne fait que passer une reference
                self.joueurs.append(self.joueur)
                self.joueurs[compteurIdJoueur].id = compteurIdJoueur
            else:
                couleurJoueur = self.controleur.serveur.getCouleurPourLeJoueur(nomJoueur)
                self.joueurs.append(joueur.Joueur(nomJoueur, couleurJoueur, partie=self, id=compteurIdJoueur))
            
            compteurIdJoueur += 1
        
        for joueur in self.joueurs: #On rempli les statuts des joueurs par rapport a tous les autres joueurs
            joueur.remplirListeStatuts()
            
        self.seed = self.controleur.getSeed()
        
        random.seed(self.seed)
        
        self.listeRessources = []
        self.listeEntites = []
        self.listeSystemes = []
        self.listeTrouDeVerre = []
        self.listeNoms = []
        
        self.genererListeNoms()
        self.genererSystemesV2(25)
        self.genererEmplacementDepart()
        
        #Pour generer des unites sur TOUTES les planetes
        #for systeme in self.listeSystemes:
        #    for planete in systeme.listePlanetes:
        #        planete.genererEmplacementDepart(self.joueurs)
        
        print("Termine initialisation de la partie")
    
    def genererListeNoms(self):
        syllabes1 = ["La", "Le", "Lo", "Li", "Lu", "Ly", "Da", "De", "Do", "Di", "Du", "Dy", "Ma", "Me", "Mo", "Mi", "Mu", "My" , "Pen"]
        syllabes2 = ["lon", "ton", "son", "don", "mon", "lan", "tan", "san", "dan", "man" , "lor", "tor", "sor", "dor", "mor", "is", "tra", "tri", "tru", "tro", "tre"]
        syllabes3 = ["myr", "tyr", "syr", "dyr", "lyr" , "da", "de", "do", "di", "du", "dy", "ba", "be", "by", "bo", "bu" , "noune"]
        
        #Generation de noms de systemes a deux syllabes
        for x in range(len(syllabes1)):
            for y in range(len(syllabes2)):
                self.listeNoms.append(syllabes1[x] + syllabes2[y])
                
        #Generation de noms de systemes a trois syllabes
        for x in range(len(syllabes1)):
            for y in range(len(syllabes2)):
                for z in range(len(syllabes3)):
                    self.listeNoms.append(syllabes1[x] + syllabes2[y] + syllabes3[z])
                    
        print("Longueur liste des noms generes pour les systemes: " + str(len(self.listeNoms)))

        
    def genererSystemesV2(self, nombreSysteme):
        zone = int(self.worldSize / math.sqrt(nombreSysteme))
        IDSysteme = 0
        
        for x in range(int(math.sqrt(nombreSysteme))):
            for y in range(int(math.sqrt(nombreSysteme))):
                nomSysteme = self.listeNoms.pop(random.randint(1, len(self.listeNoms) - 1))
                self.listeSystemes.append((Systeme.Systeme(self, IDSysteme, self.seed + IDSysteme, nomSysteme, random.randint(5, zone - 5) + x * zone, random.randint(5, zone - 5) + y * zone, self.worldSize)))
                IDSysteme = IDSysteme + 1
                
    def collecterRessourcesSurChaquePlanete(self, frame, joueur):
        if frame % 20 == 0: 
            for systeme in self.listeSystemes:
                for planete in systeme.listePlanetes:
                    planete.collecterRessources(joueur)
    
    
    def genererEmplacementDepart(self):
        #Pour chaque joueur, choisis un systeme solaire de d￩part selon un un Cadran de la galaxie
        # Joueur 1: en haut a gauche
        # Joueut 2: en bas a droite ... etc
        zone = int(self.worldSize / 3)
        
        print("Liste des joueurs: " + str(self.joueurs))
        for n in range(len(self.joueurs)):
            if n == 0: ## haut gauche
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX < zone and self.listeSystemes[i].posY < zone:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 1: ## bas droite
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX > zone * 2 and self.listeSystemes[i].posY > zone * 2:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 2: ## 
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX > zone * 2 and self.listeSystemes[i].posY < zone:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 3:
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX < zone and self.listeSystemes[i].posY > zone * 2:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 4:  # haut milieu
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX > zone and self.listeSystemes[i].posX < zone * 2 and self.listeSystemes[i].posY < zone:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 5: # bas milieu
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX < zone and self.listeSystemes[i].posX < zone * 2 and self.listeSystemes[i].posY > zone * 2:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 6: # droite milieu
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX > zone * 2 and self.listeSystemes[i].posY > zone and self.listeSystemes[i].posY < zone * 2:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            if n == 7: # gauche milieu
                for i in range(len(self.listeSystemes)):
                    if self.listeSystemes[i].posX < zone and self.listeSystemes[i].posY > zone and self.listeSystemes[i].posY < zone * 2:
                        self.listeSystemes[i].trouverPlaneteDepart(self.joueurs[n].nom, n)
                        break
            
        
    def genererTrouDeVerre(self, nombreTrouDeVerre): # pas complet
        for nb in range(nombreTrouDeVerre):
            TrouDeVerreEnPlace = False

            while not TrouDeVerreEnPlace:
                posX = random.randint(1, self.worldSize)
                posY = random.randint(1, self.worldSize)
                if len(self.listeTrouDeVerre) == 0:
                    self.listeTrouDeVerre.append([posX, posY])
                else:
                    for i in range(len(self.listeTrouDeVerre)):
                        if posX > self.listeTrouDeVerre[i][0].posX - 10 and posX < self.listeTrouDeVerre[i][0].posX + 10 and posY > self.listeTrouDeVerre[i][1].posY - 5 and posY < self.listeTrouDeVerre[i][1].posY + 5:
                            TrouDeVerreEnPlace = False
                            #print("false")
                            break 
                        else:
                            TrouDeVerreEnPlace = True
                            #print("true")
                            
                    if TrouDeVerreEnPlace == True:
                        self.listeTrouDeVerre.append([posX, posY])
                        
######################################
#######
#######  M￉THODE D'ACC￈S
#######
######################################

    def constructionPossible(self,joueur):
        return False
                    
    def vuePlaneteDepart(self, nomJoueur):
        for systeme in self.listeSystemes:
            for planete in systeme.listePlanetes:
                for i in range(len(planete.listeEntites)):
                    if planete.listeEntites[i].joueur == nomJoueur:
                        print("Joueur: " + planete.listeEntites[i].joueur + " sur la planete: " + planete.nom)
                        #for r in range(len(systeme.ressourcesJoueur)):
                        systeme.ressourcesJoueur[0]=200
                        systeme.ressourcesJoueur[1]=200
                        systeme.ressourcesJoueur[2]=200
                        systeme.ressourcesJoueur[3]=200
                        return planete    
                        
    def typeVue(self):
        return "Galaxie"

    def systemeSelectionnee(self, posX, posY):
        for i in range(len(self.listeSystemes)):
            if self.listeSystemes[i].posX == posX and self.listeSystemes[i].posY == posY:
                return self.listeSystemes[i]
        
    def estVueSystemePossible(self, systeme, nomJoueur):
        for i in range(len(systeme.listeEntites)):
            if systeme.listeEntites[i].joueur.nom == nomJoueur:
                return True
        return False
            
    def trouverSystemeParID(self, ID):
        for systeme in self.listeSystemes:
            if systeme.ID == ID:
                return systeme

    def trouverEntiteParId(self, id):
        for entite in self.listeEntites:
            if entite.id == id:
                return entite
            
        return None
               
    def getMyIp(self):
        return socket.gethostbyname(socket.gethostname())
       
class ListePrix(): #Liste de tous les prix pour chacune des unite et batiments du jeux
    def __init__(self):
#       les ressources dans un ordre precis soit le meme que l'affichage
#       donc : "fer", "petrole","fertilite","gaz","titane","cuivre","or","argent"
#       Si une ressource n'est pas necessaire on met un 0.
        self.tank = [100, 0, 0, 0, 0, 0, 0, 0]
        self.vaisseau = [100, 0, 0, 0, 0, 0, 0, 0]
        self.explorateur = [0, 0, 0, 0, 0, 0, 0, 0]
        self.transporteur = [0, 0, 0, 0, 0, 0, 0, 0]
        self.fregate = [0, 0, 0, 0, 0, 0, 0, 0]
        self.colonisateur = [0, 0, 0, 0, 0, 0, 0, 0]
        self.croiseur = [0, 0, 0, 0, 0, 0, 0, 0]
        self.usine = [100, 0, 0, 0, 0, 0, 0, 0]
        self.tour = [0, 0, 0, 0, 0, 0, 0, 0]
        self.caserne = [0, 0, 0, 0, 0, 0, 0, 0]
        self.stationSpatiale = [100, 0, 0, 0, 0, 0, 0, 0]
        self.mine = [0, 0, 0, 0, 0, 0, 0, 0] #gratuit sinon on ne pourrait jamais rien construire .. On pourrait mettre des ressources de bases, à voir
        self.ferme = [100, 0, 0, 0, 0, 0, 0, 0]
        self.habitation = [100, 0, 0, 0, 0, 0, 0, 0]
        self.centreRecherche = [100, 0, 0, 0, 0, 0, 0, 0]
        self.centreCommunication = [100, 0, 0, 0, 0, 0, 0, 0]
        
        #upgrade
        self.upgradeArme1 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeArme2 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeArme3 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeBouclier1 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeBouclier2 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeBouclier3 = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeCroiseur = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeFregate = [100, 0, 0, 0, 0, 0, 0, 0]
        self.upgradeExplorateur = [100, 0, 0, 0, 0, 0, 0, 0]
                
    def getPrixUnite(self, unite):
#       unite est le nom en string du véhicule dont
#       dont on veut avoir le prix. Renvoie la bonne liste de ressources pour l'unite.
        if unite == "Tank":
            return self.tank
        elif unite == "Vaisseau":
            return self.vaisseau
        elif unite == "Explorateur":
            return self.explorateur
        elif unite == "Transporteur":
            return self.transporteur
        elif unite == "Fregate":
            return self.fregate
        elif unite == "Colonisateur":
            return self.colonisateur
        elif unite == "Croiseur":
            return self.croiseur
        
    def getPrixBatiment(self, batiment):
#       comme pour les unites mais c'est un batiment cette fois.
        if batiment == "Caserne":
            return self.caserne
        elif batiment == "Usine":
            return self.usine
        elif batiment == "Tour":
            return self.tour
        elif batiment == "Station Spatiale":
            return self.stationSpatiale
        elif batiment == "Mine":
            return self.mine
        elif batiment == "Ferme":
            return self.ferme
        elif batiment == "Habitation":
            return self.habitation
        elif batiment == "Centre de Recherche":
            return self.centreRecherche
        elif batiment == "Centre de Communication":
            return self.centreCommunication
    
    def getPrixUpgrade(self, upgrade):
        if upgrade == "upgrade Explorateur":
            return self.upgradeExplorateur
        elif upgrade == "upgrade Fregate":
            return self.upgradeFregate
        elif upgrade == "upgrade Croiseur":
            return self.upgradeCroiseur
        elif upgrade == "upgrade Arme1":
            return self.upgradeArme1
        elif upgrade == "upgrade Arme2":
            return self.upgradeArme2
        elif upgrade == "upgrade Arme3":
            return self.upgradeArme3
        elif upgrade == "upgrade Bouclier1":
            return self.upgradeBouclier1
        elif upgrade == "upgrade Bouclier2":
            return self.upgradeBouclier2
        elif upgrade == "upgrade Bouclier3":
            return self.upgradeBouclier3
        
    def getTempsCreation(self, entite):
#       comme pour les unites mais c'est un batiment cette fois.
        if entite == "Caserne":
            return 120
        elif entite == "Usine":
            return 120
        elif entite == "Tour":
            return 120
        elif entite == "Station Spatiale":
            return 120
        elif entite == "Mine":
            return 120
        elif entite == "Ferme":
            return 120
        elif entite == "Habitation":
            return 120
        elif entite == "Centre de Recherche":
            return 120
        elif entite == "Centre de Communication":
            return 120
        
        elif entite == "Tank":
            return 120
        elif entite == "Vaisseau":
            return 120
        elif entite == "Explorateur":
            return 120
        elif entite == "Transporteur":
            return 120
        elif entite == "Fregate":
            return 120
        elif entite == "Colonisateur":
            return 120
        elif entite == "Croiseur":
            return 120
        
        elif entite == "upgrade Explorateur":
            return 150
        elif entite == "upgrade Fregate":
            return 150
        elif entite == "upgrade Croiseur":
            return 150
        elif entite == "upgrade Arme1":
            return 150
        elif entite == "upgrade Arme2":
            return 150
        elif entite == "upgrade Arme3":
            return 150
        elif entite == "upgrade Bouclier1":
            return 150
        elif entite == "upgrade Bouclier2":
            return 150
        elif entite == "upgrade Bouclier3":
            return 150
  
class Controleur():
    def __init__(self, worldSize, widthEspaceJeu, heightEspaceJeu):
        self.partie = Partie(self, worldSize, widthEspaceJeu, heightEspaceJeu)
        self.vue = v.Vue(self, self.partie)
        self.actionsAEnvoyer = [] #Actions a envoyer au serveur
        self.actionsAFaire = [] #Actions dans la "queue" a faire a chaque tour de boucle
        self.serveur = None
    
    def determinerEtapeAAfficher(self):
        self.vue.master.after(50, self.determinerEtapeAAfficher)
                
        if self.partie.etapeEnCours == "Login":
            if not self.partie.loginDejaAffiche:
                self.vue.afficherLogin()
            
        elif self.partie.etapeEnCours == "Lobby":
            if self.serveur.isPartieDemarree():
                self.partie.etapeEnCours = "Partie"
            else:
                self.vue.afficherLobby()
                                
        elif self.partie.etapeEnCours == "Partie":
            if not self.partie.initialisationPartieEnvoyee:
                self.initialisationsPartieDemarree()
                self.vue.initialiserAffichagePartie()
                self.initialisationPartieTerminee = True
            else:
                if self.partie.initialisationPartieTerminee:
                    self.frameIncrement()
                    self.vue.rafraichirAffichagePartie()
                
    def notifierDejaAffiche(self):
        if self.partie.etapeEnCours == "Login":
            self.partie.loginDejaAffiche = True
        elif self.partie.etapeEnCours == "Lobby":
            self.partie.lobbyDejaAffiche = True
        elif self.partie.etapeEnCours == "Partie":
            self.partie.initialisationPartieEnvoyee = True
                
    def validerLogin(self, adresseServeur, nomJoueur, motDePasse):
        try:
            self.serveur = Pyro4.core.Proxy("PYRO:serveur@" + adresseServeur + ":54440") #Creation de la connexion sur le serveur
            connexionReussie = self.serveur.validerLogin(nomJoueur, motDePasse) #Va verifier sur le serveur si les informations de login sont valides
        except Pyro4.errors.CommunicationError:
            print("Le serveur a l'adresse " + adresseServeur + " est introuvable.")
        except:
            print("Utilisateur deja connecte a l'aide d'un autre client")
        else:
            if connexionReussie:
                couleurJoueur = self.serveur.getCouleurPourLeJoueur(nomJoueur)
                
                self.partie.joueur = joueur.Joueur(nomJoueur, couleurJoueur, partie=self.partie)
                
                if self.serveur.isPartieDemarree():
                    self.partie.etapeEnCours = "Partie"
                else:
                    self.partie.etapeEnCours = "Lobby" #L'etape du login a reussie, donc on indique au systeme d'afficher le lobby
            else:
                print("Usager " + nomJoueur + " inexistant, mot de passe invalide, ou utilisateur connecte")
    
    def initialisationsPartieDemarree(self):
        self.partie.etapeEnCours = "Partie"
        self.notifierDejaAffiche()
        
        self.partie.currentFrame = self.serveur.getMaxFrame()
        self.partie.debutPartie()
            
    def frameIncrement(self):
        if self.serveur.getGeneralFreeze() == self.partie.currentFrame and self.serveur.getGeneralFreeze() != 0:
            print("Freeze jusqu'a " + str(self.serveur.getGeneralFreeze()) + " presentement a " + str(self.partie.currentFrame))
        else:
            #Afin de ne pas perdre d'actions pendant que les donnees sont transmises au serveur
            copie_ActionsAEnvoyer = self.actionsAEnvoyer
            self.actionsAEnvoyer = []
            
            self.partie.currentFrame = self.partie.currentFrame + 1
            self.partie.collecterRessourcesSurChaquePlanete(self.partie.currentFrame, self.partie.joueur.nom)
            try:      
                actionsRecues = self.serveur.receptionFrame(self.partie.joueur.nom, self.partie.currentFrame, copie_ActionsAEnvoyer)
                
                for action in actionsRecues:
                    action.parent = self.partie
                    self.ajouterOuModifierAction(self.actionsAFaire, action)                        
                
                for i in reversed(range(len(self.actionsAFaire))):
                    if self.actionsAFaire[i].frame == self.partie.currentFrame:
                        action = self.actionsAFaire[i]
                        del self.actionsAFaire[i]
                        action.effectuerAction()
                #self.repositionnerUnites()
                
            except ValueError as ve:
                print("Joueur deconnecte")
    
    def repositionnerUnites(self):
        copieUnitesAVerifierCollisions = self.partie.unitesAVerifierCollisions
        self.partie.unitesAVerifierCollisions = []
        
        for infoUnite in copieUnitesAVerifierCollisions:
            unite = infoUnite[0]
            
            systemeId = infoUnite[1]
            planeteId = infoUnite[2]
            groupeUnitesEnCollision = []
            
            if unite not in self.partie.unitesDejaRepositionnees and not unite.enDeplacement and not unite.enRepositionnement:
                groupeUnitesEnCollision.append(unite)
                
                for entite in self.partie.listeSystemes[systemeId].listePlanetes[planeteId].listeEntites:
                    if entite not in self.partie.unitesDejaRepositionnees and entite.id != unite.id and entite.detecterCollision(unite) and not entite.enDeplacement and not entite.enRepositionnement:
                        groupeUnitesEnCollision.append(entite)
                
                if len(groupeUnitesEnCollision) > 1:
                    if len(groupeUnitesEnCollision) % 2 == 0: 
                        sousGroupe1 = len(groupeUnitesEnCollision) / 2
                    else:
                         sousGroupe1 = (len(groupeUnitesEnCollision) + 1) / 2
                         
                    for i in range(len(groupeUnitesEnCollision)):
                        if i == 0:
                            groupeUnitesEnCollision[i].targetPosX = groupeUnitesEnCollision[i].posX
                            groupeUnitesEnCollision[i].targetPosY = groupeUnitesEnCollision[i].posY
                            groupeUnitesEnCollision[i].enRepositionnement = True
                        elif i < sousGroupe1:
                            groupeUnitesEnCollision[i].targetPosX = groupeUnitesEnCollision[0].posX - i * groupeUnitesEnCollision[0].dimX - 1
                            groupeUnitesEnCollision[i].targetPosY = groupeUnitesEnCollision[i].posY
                            groupeUnitesEnCollision[i].enRepositionnement = True
                        else:
                            groupeUnitesEnCollision[i].targetPosX = groupeUnitesEnCollision[0].posX + (i - sousGroupe1 + 1) * groupeUnitesEnCollision[0].dimX + 1
                            groupeUnitesEnCollision[i].targetPosY = groupeUnitesEnCollision[i].posY
                            groupeUnitesEnCollision[i].enRepositionnement = True
                        
                        resultatDeplacement = groupeUnitesEnCollision[i].deplacementParUnTic(groupeUnitesEnCollision[i].targetPosX, groupeUnitesEnCollision[i].targetPosY, 0)
                        
                        if resultatDeplacement:
                            groupeUnitesEnCollision[i].posX = groupeUnitesEnCollision[i].posX + resultatDeplacement[4] - groupeUnitesEnCollision[i].posX
                            groupeUnitesEnCollision[i].posY = groupeUnitesEnCollision[i].posY + resultatDeplacement[5] - groupeUnitesEnCollision[i].posY
                            self.partie.unitesAVerifierCollisions.append([groupeUnitesEnCollision[i], systemeId, planeteId])
                            
                        self.partie.unitesDejaRepositionnees.append(groupeUnitesEnCollision[i])
            
            elif unite.enRepositionnement:
                resultatDeplacement = unite.deplacementParUnTic(unite.targetPosX, unite.targetPosY, 0)
                
                if resultatDeplacement:
                    unite.posX = unite.posX + resultatDeplacement[4] - unite.posX
                    unite.posY = unite.posY + resultatDeplacement[5] - unite.posY
                    self.partie.unitesAVerifierCollisions.append([unite, systemeId, planeteId])
                            
                self.partie.unitesDejaRepositionnees.append(unite)                
                                        
        self.partie.unitesDejaRepositionnees = []
        
    def creerNouveauCompte(self, nomUtilisateur, motDePasse):
        try: #Verifie si l'usager a bien ete ajoute
            self.serveur.creerNouveauCompte(nomUtilisateur, motDePasse)
        except sqlite3.IntegrityError: #L'exception avertit le client que le nom d'utilisateur existe deja
            print("Impossible d'ajouter l'utilisateur " + nomUtilisateur + ", car il est deja present dans la base de donnees")
            
    def creerListeJoueurs(self):
        return self.serveur.retournerListeJoueurs()
    
    def deconnexion(self):
        try:
            self.serveur.retirerDeLaListe(self.getJoueurCourant())
        except:
            print("Il n'y avait pas de joueur a enlever de la liste de joueurs")
        finally:
            self.vue.master.destroy()
            sys.exit()
            raise SystemExit
        
    def insererTexteChat(self, texte):
        self.serveur.insererTexteChat(self.getJoueurCourant(), texte)
        
    def creeListeChat(self):
        return self.serveur.creeListeChat()
    
    def retournerListeCouleursJoueurs(self):
        return self.serveur.retournerListeCouleurs()
    
    def getIpServeur(self):
        return self.serveur.getIp()
    
    def getCreateurPartie(self):
        return self.serveur.getCreateurPartie()
    
    def envoiDebutPartie(self):
        self.serveur.debuterPartie()
        
    def getSeed(self):
        return self.serveur.getSeed()
    
    def getMyIp(self):
        return self.partie.getMyIp()
    
    def getJoueurCourant(self):
        return self.partie.joueur.nom
    
    def ajouterOuModifierAction(self, listeActions, actionAAjouter):
        indexActionTrouvee = -1
        
        for indexAction in range(len(listeActions)): #Boucle qui verifie s'il y a deja une action avec le meme entiteId, si oui, on remplace son action par la nouvelle action
            if listeActions[indexAction].entiteId == actionAAjouter.entiteId:
                indexActionTrouvee = indexAction
                break
            
        if indexActionTrouvee > -1:
            listeActions[indexActionTrouvee] = actionAAjouter
        else: #Si l'entite n'avait pas deja d'action, on ajoute l'action qu'il a a faire
            listeActions.append(actionAAjouter)

    def sortirUnitePlanete(self, listeUnites, systemeId, planeteId):
        for unite in listeUnites:
            monAction = action.ActionSortirPlanete(None, 0, unite[1], systemeId, planeteId)
        
            self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)

    def entrerUnitePlanete(self, listeUnites, systemeId, planeteId):
        for unite in listeUnites:
            monAction = action.ActionEntrerPlanete(None, 0, unite[1], systemeId, planeteId)
        
            self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)

    def changerSysteme(self, listeUnites, systemeId, systemeCourant):
        for unite in listeUnites:
            monAction = action.ActionChangerSysteme(None, 0, unite[1], systemeCourant, systemeId, None)
        
            self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
     
    def deplacerUnite(self, entiteId, planeteId, systemeId, xFinal, yFinal, zFinal):
        monAction = action.ActionDeplacement(None, 0, entiteId, systemeId, planeteId, xFinal, yFinal, zFinal) #Creation de l'action correspondant au mouvement de l'unite

        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction) #On utilise la methode pour ajouter ou modifier la liste contenant les actions a faire
    
    def attaquerUnite(self, entiteId, targetId, planeteId, systemeId):
        monAction = action.ActionAttaquer(None, 0, entiteId, targetId, systemeId, planeteId) #Creation de l'action correspondant a l'attaque d'une unite
        
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction) #On utilise la methode pour ajouter ou modifier la liste contenant les actions a faire
        
    def ressourcesDispo(self, ressourcesJoueur, typeConstruction, uniteOuBatiment):
        self.prixConstruction = ""
        
        if uniteOuBatiment == "batiment":
            self.prixConstruction = self.partie.listePrix.getPrixBatiment(typeConstruction)
        elif uniteOuBatiment == "unite":
            self.prixConstruction = self.partie.listePrix.getPrixUnite(typeConstruction)
        
        for i in range(len(ressourcesJoueur)):
            if ressourcesJoueur[i - 1] < self.prixConstruction[i - 1]:
                return False
        return True

    def creerBatiment(self, systemeId, planeteId, typeBatiment, posX, posY, posZ):
        IDBatiment = self.serveur.genererId()
        monAction = action.ActionCreerBatiment(None, 0, IDBatiment, systemeId, planeteId, typeBatiment, posX, posY, posZ, self.partie.joueur.nom)
        
        self.prixBatiment = self.partie.listePrix.getPrixBatiment(typeBatiment)
        for i in range(len(self.prixBatiment)):
            if self.prixBatiment[i - 1] > 0:
                self.partie.trouverSystemeParID(systemeId).ressourcesJoueur[i - 1] = self.partie.trouverSystemeParID(systemeId).ressourcesJoueur[i - 1] - self.prixBatiment[i - 1]
        
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction) #On utilise la methode pour ajouter ou modifier la liste contenant les actions a faire
       
       
       
    def creerUnite(self, systemeId, planeteId, typeUnite, posX, posY, posZ, rallyX, rallyY, rallyZ):
        IDUnite = self.serveur.genererId()
    
        monAction = action.ActionCreerUnite(None, 0, IDUnite, systemeId, planeteId, posX, posY, posZ, rallyX, rallyY, rallyZ, typeUnite, self.partie.joueur.nom)
        self.prixUnite = self.partie.listePrix.getPrixUnite(typeUnite)
        for i in range(len(self.prixUnite)):
            if self.prixUnite[i - 1] > 0:
                self.partie.trouverSystemeParID(systemeId).ressourcesJoueur[i - 1] = self.partie.trouverSystemeParID(systemeId).ressourcesJoueur[i - 1] - self.prixUnite[i - 1]
        
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
    
    #def creerBarreProgression(self):
        
    
    def dessinerAttaque(self, uniteAttaquante, uniteAttaquee):
        coordUniteAttaquante = (uniteAttaquante.posX, uniteAttaquante.posY)
        coordUniteAttaquee = (uniteAttaquee.posX, uniteAttaquee.posY)
        
        self.vue.dessinerAttaque(coordUniteAttaquante, coordUniteAttaquee)
    #Verifie le status et le modifie si necessaire.  Utilise lors des attaques
    def verifierStatus(self, nomJoueur):
        if(not self.partie.joueur.isStatus(nomJoueur, self.partie.joueur.nom, "allie")):
            if(self.partie.joueur.isStatus(nomJoueur, self.partie.joueur.nom, "neutre") == True):
                #Si la cible est neutre, change le status du joueur adverse a ennemi
                self.modifierStatus(nomJoueur, self.partie.joueur.nom, "ennemi")
            return True
        else:
            return False
        
    def modifierStatus(self, nomJoueur1, nomJoueur2, newStatus):
        monAction = action.ActionChangerStatus(None, self.partie.currentFrame + 1, None, None, None, nomJoueur1, nomJoueur2, newStatus)
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
        
    def getHeightEspaceJeu(self):
        return self.partie.heightEspaceJeu
    
    def getWidthEspaceJeu(self):
        return self.partie.widthEspaceJeu
    
    #Pour envoyer une ActionEnvoyerDemande
    def envoyerDemande(self, demande):
        #print("Envoie de la demande : " + demande)
        monAction = action.ActionEnvoyerDemande(None, self.partie.currentFrame + 1, None, None, None, demande)
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
        print("Demande envoyée")
        
    #Pour supprimer une demande de la liste
    def actionSupprimerDemande(self, demande):
        monAction = action.ActionSupprimerDemande(None, self.partie.currentFrame + 1, None, None, None, demande)
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
    
    def actionChangerStatus(self, nomJoueur, status):
        monAction = action.ActionChangerStatus(None, self.partie.currentFrame + 1, None, None, None, self.getJoueurCourant(), nomJoueur, status)
        self.ajouterOuModifierAction(self.actionsAEnvoyer, monAction)
    
    def accepterDemande(self, demande):
        self.envoyerDemande(demande)
        self.actionChangerStatus(demande[1], demande[2])
    
    #Retourne la liste de status qui touchent au joueur
    def getListeStatus(self):
        return self.partie.joueur.statusConcernes()
    
    def getStatusJoueur(self, nomJoueur):
        return self.partie.joueur.getStatusJoueur(nomJoueur)
    
    #Retourne la couleur d'un joueur en cherchant avec son nom
    def getCouleurJoueur(self, nomJoueur):
        listeCouleurs = self.retournerListeCouleursJoueurs()
        laCouleur = listeCouleurs[self.partie.joueurs.index(nomJoueur)]
        return laCouleur
    
    def notificationDiplomatie(self):
        self.vue.notificationDiplomatie()
        
    def traiterDemandes(self):
        self.partie.joueur.traiterDemandes()
    
    def verifierRessources(self, frame, systemeId, planeteId, achat, type):
        systeme = self.partie.listeSystemes[systemeId]
        
        if type == "upgrade":
            cout = self.partie.listePrix.getPrixUpgrade(achat)
        
        elif type == "unite":
            cout = self.partie.listePrix.getPrixUnite(achat)
        
        elif type == "batiment":
            cout = self.partie.listePrix.getPrixBatiment(achat)
            
        monAction = action.Action(None, frame, None, systemeId, planeteId).verifierRessources(systeme.ressourcesJoueur, cout)
        
        if(monAction):
            if type == "upgrade":
                pass
                #batiment.Centre --Centre n'existe pas (et batiment n'etait meme pas importe), je ne comprend pas ce que tu essaies de faire ici
            
        
if __name__ == "__main__":
    worldSize = 1000
    widthEspaceJeu = 800
    heightEspaceJeu = 600
    
    controleur = Controleur(worldSize, widthEspaceJeu, heightEspaceJeu)
    controleur.determinerEtapeAAfficher()